#pragma once

#include <string>

namespace renderit
{
	namespace core
	{
		class cbuffer
		{
		public:
			cbuffer()
				: buf_(static_buf_)
				, size_(0)
				, capacity_(1024)
			{

			}

			~cbuffer()
			{
				if (buf_ != static_buf_) {
					delete[] buf_;
				}
			}

		public:
			void add(char c)
			{
				reserve(1);
				buf_[size_++] = c;
			}

			void add(const char * p, int len)
			{
				reserve(len);
				memcpy(&buf_[size_], p, len);
				size_ += len;
			}

			void add_at(int pos, const char * p, int len)
			{
				if (pos + len > size_) {
					int size = pos + len;
					reserve(size - size_);
					size_ = size;
				}

				memcpy(&buf_[pos], p, len);
			}

			int size() const
			{
				return size_;
			}

			char * buf()
			{
				return buf_;
			}

			void reserve(int size)
			{
				if (size_ + size > capacity_) {
					capacity_ = size_ + size + 256;
					const char * old_buf = buf_;
					buf_ = new char[capacity_];
					memcpy(buf_, old_buf, size_);
					if (old_buf != static_buf_) {
						delete[] old_buf;
					}
				}
			}

			int tell() const
			{
				return size_;
			}

			void resize(int size)
			{
				if (size > capacity_) {
					reserve(size - size_);
				}
				size_ = size;
			}

			char tail() const
			{
				return buf_[size_ - 1];
			}

		private:
			char static_buf_[1024];
			char * buf_;
			int size_;
			int capacity_;
		};
	}
}